const assert = require("assert")
const Router = require("express").Router
const router = new Router()
const moment = require('moment');
const {errorWrapper} = require("../utils/errorWrapper")
const {success} = require("../utils/success")
const mammoth = require("mammoth")
const Contest = require("../models/models/Contest")
const Admini = require("../models/models/Admini")
const Notice = require("../models/models/Notice")
const Score = require("../models/models/Score")
const Adv = require("../models/models/Adv")
const RequestNum = require("../models/models/RequestNum")
const {Token} = require("../models/models/Token")

var fs = require("fs");
const readline = require("readline")

const multer = require('multer');

const upload = multer({
    dest: './upload'
});
const img = multer({
    dest: './public/img/'
});

const AESKEY = "hello"

const User = require("../models/models/User")
const Apply = require("../models/models/Apply")
const cryptoJS = require("crypto-js");
const Work = require("../models/models/Work");
const NodeRSA = require("node-rsa");
const Key = require("../models/models/Key");

// 获取请求次数
router.post("/GetRequestNum", errorWrapper(async (req, res) => {
    const re = await RequestNum.findOne()
    res.json(success({num: re.num}))
}))

// 获取全部学生用户数据
router.post("/GetAllUserInfo", errorWrapper(async (req, res) => {
    const {limit, skip, name, collegeName} = req.body
    let query = []
    let obj = {}

    if (collegeName !== 'undefined') {
        obj.collegeName = collegeName
    }
    if (name) {
        obj.name = name
    }
    query.push(obj)
    const user = await User.find({$and: query}).limit(limit).skip(skip)
    user.forEach(v => {
        v.pwd = cryptoJS.AES.decrypt(v.pwd, AESKEY).toString(cryptoJS.enc.Utf8)
    })
    res.json(success({user}))
}))

// 获取全部管理员用户数据
router.post("/GetAdminInfo", errorWrapper(async (req, res) => {
    const {limit, skip, collegeName, name} = req.body
    let query = []
    let obj = {}

    if (collegeName !== 'undefined') {
        obj.collegeName = collegeName
    }
    if (name) {
        obj.name = name
    }
    query.push(obj)
    const admin = await Admini.find({$and: query}).limit(limit).skip(skip)
    admin.forEach(v => {
        v.pwd = cryptoJS.AES.decrypt(v.pwd, AESKEY).toString(cryptoJS.enc.Utf8)
    })
    res.json(success({admin}))
}))

// 删除管理员用户
router.post("/DelAdminUser", errorWrapper(async (req, res) => {
    const {id} = req.body
    if (id) {
        await Admini.findByIdAndDelete(id)
    } else {
        await Admini.deleteMany()
    }
    console.log(id)
    res.json(success())
}))

// 更新管理员用户
router.post("/UpdateByIdAdminUserInfo", errorWrapper(async (req, res) => {
    const {id, formData} = req.body
    formData.pwd = cryptoJS.AES.encrypt(formData.pwd, AESKEY).toString()
    if (id !== '')
        await Admini.findByIdAndUpdate(id, formData)
    else {
        const admin = await new Admini(formData).save()
        const key = new NodeRSA({b: 512})
        key.generateKeyPair(2048, 65537)
        // 导出密钥
        const publicKey = key.exportKey("pkcs1-public")
        const privateKey = key.exportKey("pkcs1-private")
        // 存入数据库
        await new Key({publicKey, privateKey, userID: admin._id}).save()
    }

    res.json(success())
}))


// 通过id删除数据
router.post("/DeleteOneById", errorWrapper(async (req, res) => {
    const {id} = req.body
    if (id) {
        await User.findByIdAndDelete(id)
    } else {
        await User.deleteMany()
    }
    res.json(success({msg: '删除成功'}))
}))

// 通过id修改用户数据
router.post("/UpdateByIdUserInfo", errorWrapper(async (req, res) => {
    const {id, formData} = req.body
    formData.pwd = cryptoJS.AES.encrypt(formData.pwd, AESKEY).toString()
    if (id !== '')
        await User.findByIdAndUpdate(id, formData)
    else {
        const user = await new User(formData).save()
        const key = new NodeRSA({b: 512})
        key.generateKeyPair(2048, 65537)
        // 导出密钥
        const publicKey = key.exportKey("pkcs1-public")
        const privateKey = key.exportKey("pkcs1-private")
        // 存入数据库
        await new Key({publicKey, privateKey, userID: user._id}).save()
    }
    res.json(success({msg: '更新成功'}))
}))

// 添加精彩记录
router.post("/AddAdv", errorWrapper(async (req, res) => {
    const {fileInfo} = req.body
    await Adv.insertMany({path: JSON.stringify(fileInfo[0])})
    res.json(success({}))
}))

// 获取精彩记录
router.post("/GetAdv", errorWrapper(async (req, res) => {
    const {limit, skip} = req.body
    const adv = await Adv.find().limit(limit).skip(skip)
    res.json(success({adv}))
}))

// 删除精彩记录
router.post("/delAdv", errorWrapper(async (req, res) => {
    const {id} = req.body
    if (id) {
        await Adv.findByIdAndDelete(id)
    } else {
        await Adv.deleteMany()
    }
    res.json(success({}))
}))

// 数据分析
router.post("/lookAt", errorWrapper(async (req, res) => {

    const apply = await Apply.aggregate([
        {
            $group: {
                _id: "$status",
                count: {
                    $sum: 1
                }
            }
        }
    ]);
    const count = await Apply.count()
    res.json(success({apply, count}))
}))

// 报名人数
router.post("/GetApplyInfoNum", errorWrapper(async (req, res) => {
    const {collegeName} = req.body
    res.json(success({count: await Apply.count({collegeName})}))
}))

// 读取日志信息
router.post("/ReadLogInfo", errorWrapper(async (req, res) => {
    let log = []
    try {
        const data = await fs.readFileSync('./log/log.txt', 'UTF-8');
        const lines = data.split(/\r?\n/);
        for (let i = 0; i < lines.length - 1; i++) {
            log.push({
                info: lines[i],
                color: '#fcad9f'
            })
        }
    } catch (err) {
        console.error(err);
    }
    res.json(success({log}))
}))

// 获取报名信息数据
router.post("/GetApplyInfoData", errorWrapper(async (req, res) => {
    const {token} = req.cookies
    const {collegeName, Sno, name, limit, skip, radio} = req.body
    // 判断token是否过期
    const t = await Token.findById(token)

    if (!t) {
        res.json(success({msg: 'token过期'}))
        return;
    }
    let query = []
    let obj = {}
    const ad = await Admini.findById(t.userID)
    if (ad.role.some(v => v.includes('SuperAdmin')))
        obj['user.collegeName'] = collegeName
    else {
        obj['user.collegeName'] = ad.collegeName
    }
    if (Sno && name) {
        obj["user.Sno"] = Sno
        obj["user.name"] = name
    }
    if (radio !== undefined) {
        obj.status = radio
    }
    query.push(obj)
    console.log(query)
    const apply = await Apply.aggregate([
        {
            $lookup: {
                from: "users",
                localField: "userID",
                foreignField: "_id",
                as: "user",
            }
        },
        {
            $lookup: {
                from: "contests",
                localField: "contestID",
                foreignField: "_id",
                as: "contest"
            }
        },
        {
            $project: {
                'user.pwd': 0
            }
        }, {
            $match: {
                $and: query
            }
        }
    ]).limit(limit).skip(skip)

    res.json(success(apply))
}))

// 添加公告
router.post("/AddNotice", errorWrapper(async (req, res) => {
    const {name, filePath, collegeName} = req.body
    await Notice.insertMany({name, content: JSON.stringify(filePath[0]), collegeName})
    res.json(success())
}))
// 获取公告
router.post("/GetNotice", errorWrapper(async (req, res) => {
    const {limit, skip, collegeName} = req.body
    const notice = await Notice.find({collegeName}).limit(limit).skip(skip)
    res.json(success({notice}))
}))

// 删除公告
router.post("/delNotice", errorWrapper(async (req, res) => {
    const {id} = req.body
    if (id) {
        await Notice.findOneAndDelete(id)
    } else {
        await Notice.deleteMany()
    }
    res.json(success({}))
}))


// 删除全部报名信息
router.post("/delAllData", errorWrapper(async (req, res) => {
    const {id} = req.body
    if (id) {
        await Apply.findOneAndDelete(id)
    } else {
        await Apply.deleteMany()
    }

    res.json(success())
}))


// 待审核信息
router.post("/UpdateStatus", errorWrapper(async (req, res) => {
    const {status, id} = req.body
    await Apply.findByIdAndUpdate(id, {status})
    res.json(success({msg: '审核成功'}))
}))

// 审核打分
router.post("/SetScore", errorWrapper(async (req, res) => {
    const {score, id} = req.body
    const s = await new Score({score, workID: id}).save()
    await Work.findByIdAndUpdate(id, {status: 1, scoreID: s._id})
    res.json(success({}))
}))

// 上传文件
router.post("/upload/file", upload.single('content'), errorWrapper(async (req, res) => {
    if (req.file.length === 0) {  //判断一下文件是否存在，也可以在前端代码中进行判断。
        res.render("error", {message: "上传文件不能为空！"});
        return
    } else {
        let file = req.file;
        let fileInfo = {};
        const path = Date.now() + file.originalname
        await fs.renameSync('./upload/' + file.filename, './upload/' + path);//这里修改文件名字，比较随意。
        // 获取文件信息
        fileInfo.name = path;
        fileInfo.path = './upload/' + path;
        // 设置响应类型及编码
        res.set({
            'content-type': 'application/json; charset=utf-8'
        });
        res.json(success({fileInfo}))
    }
}))

// 删除作品
router.post("/delWork", errorWrapper(async (req, res) => {
    const {id} = req.body
    if (id) {
        await Work.findOneAndDelete(id)
    } else {
        await Work.deleteMany()
    }
    res.json(success())
}))

// 获取报名成功提交作品的信息表
router.post("/appraise", errorWrapper(async (req, res) => {
    const {limit, skip} = req.body
    const w = await Work.find({status: 0}).limit(limit).skip(skip)
    res.json(success({w}))
}))

// 获取作品信息
router.post("/GetWork", errorWrapper(async (req, res) => {
    const {collegeName, limit, skip} = req.body
    const {token} = req.cookies
    // 判断token是否过期
    const t = await Token.findById(token)
    if (!t) {
        res.json(success({msg: 'token过期'}))
        return;
    }
    let query = []
    let obj = {}
    const ad = await Admini.findById(t.userID)
    if (ad) {
        if (ad.role.some(v => v.includes('SuperAdmin')))
            obj['user.collegeName'] = collegeName
        else {
            obj['user.collegeName'] = ad.collegeName
        }
    }
    query.push(obj)

    const w = await Work.aggregate([
        {
            $lookup: {
                from: "users",
                localField: "userID",
                foreignField: "_id",
                as: "user"
            }
        },
        {
            $lookup: {
                from: "scores",
                localField: "scoreID",
                foreignField: "_id",
                as: "score"
            }
        }, {
            $project: {
                'name': 1,
                'path': 1,
                '_id': 1,
                'createTime': 1,
                "updateTime": 1,
                'status': 1,
                'isTeam': 1,
                'user.name': 1,
                'user.collegeName': 1,
                'score.score': 1
            }
        }, {
            $match: {
                $and: query
            }
        }
    ]).limit(limit).skip(skip)
    res.json(success({w}))
}))


// 上传图片
router.post("/upload/img", img.single('img'), errorWrapper(async (req, res) => {
    if (req.file.length === 0) {  //判断一下文件是否存在，也可以在前端代码中进行判断。
        res.render("error", {message: "上传文件不能为空！"});
        return
    } else {
        let file = req.file;
        let fileInfo = {};
        const path = Date.now() + file.originalname
        await fs.renameSync('./public/img/' + file.filename, './public/img/' + path);//这里修改文件名字，比较随意。
        // 获取文件信息
        fileInfo.name = path;
        fileInfo.path = './public/img/' + path;
        // 设置响应类型及编码
        res.set({
            'content-type': 'application/json; charset=utf-8'
        });
        res.json(success({fileInfo}))
    }
}))

// 添加比赛信息
router.post("/PushContest", errorWrapper(async (req, res) => {
    const {
        name,
        tel,
        raceType,
        genre,
        userName,
        organizer,
        startDate,
        endDate,
        filePath,
        applyStartDate,
        applyEndDate,
        collegeName
    } = req.body
    let param = {
        name,
        tel,
        raceType,
        genre,
        userName,
        organizer,
        startDate,
        endDate,
        applyStartDate,
        applyEndDate,
        collegeName
    }
    assert.ok(name !== "", "请输入名称")
    param.img = JSON.stringify(filePath[1])
    param.content = JSON.stringify(filePath[0])
    await Contest.insertMany(param)
    res.json(success({msg: '添加成功'}))
}))

// h获取竞赛类别
router.post("/GetGenre", errorWrapper(async (req, res) => {
    const c = await Contest.aggregate([{
        $group: {
            _id: '$genre',
            count: {$sum: 1}
        }
    }])
    res.json(success({c}))
}))

// 获取竞赛信息
router.post("/GetContestInfo", errorWrapper(async (req, res) => {
    const {limit, skip, collegeName, status} = req.body
    let query = []
    let obj = {}
    if (collegeName) {
        obj.collegeName = collegeName
    }
    if (status !== 'undefined') {
        obj.status = status
    }
    query.push(obj)
    const con = await Contest.find({$and: query}).limit(limit).skip(skip)
    let data = []
    if (con) {
        for (let i = 0; i < con.length; i++) {
            let param = JSON.parse(con[i].content)
            const ma = await mammoth.convertToHtml({path: param.path})
            param['text'] = ma.value
            con[i].content = JSON.stringify(param)
            data.push(con[i])
        }
    }
    const count = await Contest.count({collegeName})
    res.json(success({con: data, count}))
}))

// 删除竞赛信息
router.post("/DelContentById", errorWrapper(async (req, res) => {
    const {id} = req.body
    if (id) {
        await Contest.findOneAndDelete(id)
    } else {
        await Contest.deleteMany()
    }
    res.json(success({}))
}))

//设置竞赛状态
router.post("/UpdateContestStatus", errorWrapper(async (req, res) => {
    const {id, status} = req.body
    console.log(status)
    await Contest.findByIdAndUpdate(id, {status})
    res.json(success({}))
}))

// 删除文件
router.post("/DelUploadFile", errorWrapper(async (req, res) => {
    const {path} = req.body
    await fs.rmSync(path)
    res.json(success({msg: '删除成功'}))
}))

// 下载文件word
router.get("/DownloadFile", errorWrapper(async (req, res) => {
    const params = JSON.parse(req.query.fileInfo)
    let {path, name} = params
    const origiName = name
    var fileStream = fs.createReadStream(path);
    name = encodeURIComponent(name)
    const stat = fs.statSync(path);
    res.setHeader('Content-type', 'application/docx');
    // res.setHeader('Content-Disposition', 'attachment;filename=1.pdf');
    res.setHeader('Content-Disposition', `attachment;filename=${name}`);
    res.setHeader('Content-Length', stat.size);
    fileStream.on('data', function (data) {
        res.write(data, 'binary');
    });
    fileStream.on('end', function () {
        res.end();
        console.log(moment().format('YYYY 年 MM 月 DD 日 h:mm:ss a') + '用户[-------下载了文件' + origiName + '-------]');
    });
}))

module.exports = router